/**
    Controlador de LCD Alfanumérica 2x16 LMB162A

    Copyright (C) 2013  Rodrigo Garcia

 This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/
#ifndef LCD_H

#define LCD_H

#include<stdio.h>
#include<avr/io.h>

#include<util/delay.h>

///hardware
#define LCD_PORT PORTD
#define LCD_DDR DDRD
///software
void delay_ms(int n)
{
  while(n--)
    {
      _delay_ms(1);
    }
}
#define RS 2
#define EN 3
void EN_pulse(void)
{
	LCD_PORT|=(1<<EN);
	_delay_us(1);
	LCD_PORT&=~(1<<EN);
}
void lcd_general(char dato,char tipo){
	LCD_PORT=dato&0xf0;
	if(tipo)PORTD|=(1<<RS);
	EN_pulse();
	LCD_PORT=(dato<<4);
	if(tipo)LCD_PORT|=(1<<RS);
	EN_pulse();
	_delay_us(40);
}
#define lcd_char(l) lcd_general(l,1)
#define lcd_cmd(c) lcd_general(c,0)

void lcd_clear(void)
{
	lcd_cmd(1);
	delay_ms(2);
}

void lcd_init(void){
	LCD_PORT=0;
	LCD_DDR|=0xFC;
	delay_ms(5);

	LCD_PORT=0x30;
	EN_pulse();
	delay_ms(5);

	LCD_PORT=0x30;
	EN_pulse();
	delay_ms(5);

	LCD_PORT=0x30;
	EN_pulse();
	delay_ms(5);

	LCD_PORT=0x20;
	EN_pulse();
	delay_ms(5);

	lcd_cmd(0x28);
	lcd_cmd(0x0E);
	lcd_cmd(0x06);
	lcd_clear();

}
//********************MANEJO DEL STDIO.H****************************

int lcd_putchar(char c,FILE *stream){  //file se agrega en stdio.h
if((c==10)||(c==13)) //habilita \n para nueva linea
	lcd_cmd(0xc0);    //comando para salto de linea
	else
	lcd_char(c); // escribe el texto
	return 0;    //retorna de donde vino con valor 0

}
FILE lcd=FDEV_SETUP_STREAM(lcd_putchar,NULL,_FDEV_SETUP_WRITE); //declaraciones de stdio.h

void print_init(void){
	lcd_init();
	stdout=&lcd; // habilita printf con ayuda de stdio.h el comando de stdio.h es enmascarado con
    // el contenido de la lcd
}

#endif
